package entity;


import entity.Wrapper;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import server.HttpServlet;
import server.MyClassLoader;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 表示一个web应用
 */
public class Context {
    //存放的路径
    private String docBase;
    //表示访问的uri的前缀路径
    private String path;

    private List<Wrapper> wrappers = new ArrayList<Wrapper>();
    private HashMap<String, HttpServlet> servletMappings = new HashMap<>();

    private ClassLoader classLoader;

    /**
     * 我们约定每个context内必须包含一个web.xml文件，所以编写他的构造方法，对web.xml进行解析
     * @param docBase
     * @param path
     */
    public Context(String docBase, String path) {
        this.docBase = docBase;
        this.path = path;
        //设置当前应用的类加载器
        MyClassLoader myClassLoader = new MyClassLoader(docBase, "");
        classLoader = myClassLoader;
        //解析当前包下的web.xml
        loadConfig();


    }

    /**
     * 封装loadconfig方法，解析web.xml并对其内的servlet进行实例化；
     *  关键代码：用自定义的类加载器加载当前应用内的类，并进行实例化，每个context有自己的类加载器
     *  HttpServlet instance =(HttpServlet)classLoader.loadClass(servletClass).newInstance();
     */


    private void loadConfig() {
        File file = new File(docBase + "/web.xml");
        SAXReader saxReader = new SAXReader();

        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            Document document = saxReader.read(fileInputStream);
            Element rootElement = document.getRootElement();

            List<Element> selectNodes = rootElement.selectNodes("//servlet");
            for (int i = 0; i < selectNodes.size(); i++) {
                Element element = selectNodes.get(i);
                // <servlet-name>lagou</servlet-name>
                Element servletnameElement = (Element) element.selectSingleNode("servlet-name");
                String servletName = servletnameElement.getStringValue();
                // <servlet-class>server.LagouServlet</servlet-class>
                Element servletclassElement = (Element) element.selectSingleNode("servlet-class");
                String servletClass = servletclassElement.getStringValue();
                //根据servlet-name的值url-pattern
                Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
                // /lagou
                String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue();
                Wrapper wrapper = new Wrapper();
                wrapper.setName(servletName);
                wrapper.setServletClassName(servletClass);
                wrapper.setUrlPattern(path+urlPattern);//servlet真实路径
                HttpServlet instance =(HttpServlet)classLoader.loadClass(servletClass).newInstance();
                wrapper.setInstance(instance);
                wrappers.add(wrapper);
                servletMappings.put(wrapper.getUrlPattern(),wrapper.getInstance());
            }
        }catch (DocumentException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    public String getDocBase() {
        return docBase;
    }

    public void setDocBase(String docBase) {
        this.docBase = docBase;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public List<Wrapper> getWrappers() {
        return wrappers;
    }

    public void setWrappers(List<Wrapper> wrappers) {
        this.wrappers = wrappers;
    }

    public HashMap<String, HttpServlet> getServletMappings() {
        return servletMappings;
    }

    public void setServletMappings(HashMap<String, HttpServlet> servletMappings) {
        this.servletMappings = servletMappings;
    }

    public ClassLoader getClassLoader() {
        return classLoader;
    }

    public void setClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }
}

/*public class Context {
    private String webName;
    private List<Wrapper> wrapperList = new ArrayList<>();

    public String getWebName() {
        return webName;
    }

    public void setWebName(String webName) {
        this.webName = webName;
    }

    public List<Wrapper> getWrapperList() {
        return wrapperList;
    }

    public void setWrapperList(List<Wrapper> wrapperList) {
        this.wrapperList = wrapperList;
    }
}*/
